package com.ld.security.shop.crawler.modules.wo.service.impl;

import cn.hutool.core.lang.Console;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.http.HttpUtil;
import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.CookieManager;
import com.gargoylesoftware.htmlunit.NicelyResynchronizingAjaxController;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.ld.security.common.core.exception.ApiException;
import com.ld.security.common.core.util.UuidUtil;
import com.ld.security.shop.crawler.modules.wo.constant.WoIpConstant;
import com.ld.security.shop.crawler.modules.wo.service.IWoIpService;
import com.ld.security.shop.crawler.modules.wo.entity.WoIp;
import com.ld.security.common.mybatis.base.service.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
class WoIpServiceImpl extends ISuperServiceImpl<WoIp> implements
        IWoIpService {

    List<WebClient> webClients;

    WebClient localWebClient;


    CloseableHttpClient httpClient = HttpClients.createDefault();

    List<RequestConfig> proxyConfigs;

    RequestConfig localConfig;

    private WebClient buildWebClient(WebClient webClient) {

//        webClient.addRequestHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0");
//        //2.设置参数
////启动js
//        webClient.getOptions().setJavaScriptEnabled(true);
////关闭css渲染
//        webClient.getOptions().setCssEnabled(false);
////启动重定向
//        webClient.getOptions().setRedirectEnabled(true);
////启动cookie管理
//        webClient.setCookieManager(new CookieManager());
////启动ajax代理
//        webClient.setAjaxController(new NicelyResynchronizingAjaxController());
////js运行时错误，是否抛出异常
//        webClient.getOptions().setThrowExceptionOnScriptError(false);
//
//        // 取消css支持
//        //webClient.getOptions().setCssEnabled(false);
        webClient.getOptions().setThrowExceptionOnScriptError(false);
        return webClient;
    }

    @Override
    public Integer init() {
        if (webClients != null) {
            for (WebClient webClient : webClients) {
                webClient.close();
            }
        }
        WoIp q = this.newInstance();
        q.setStatus(WoIpConstant.status.normal);
        List<WoIp> list = this.all(q);

        webClients = list.stream().map(val -> {
            WebClient webClient = new WebClient(BrowserVersion.CHROME, val.getHost(), val.getPort());
            return this.buildWebClient(webClient);
        }).collect(Collectors.toList());

        proxyConfigs = list.stream().map(val -> {
            HttpHost proxy = new HttpHost(val.getHost(), val.getPort());
            RequestConfig requestConfig = RequestConfig.custom().setProxy(proxy).build();
            return requestConfig;
        }).collect(Collectors.toList());

        localConfig = RequestConfig.custom().build();

        localWebClient = new WebClient(BrowserVersion.CHROME);
        this.buildWebClient(localWebClient);
        return webClients.size();
    }

    boolean debug = false;

    private RequestConfig getProxyConfig() {
        if (proxyConfigs == null) {
            synchronized (this.getClass()) {
                if (proxyConfigs == null) {
                    this.init();
                }
            }
        }

        if (proxyConfigs.size() > 0) {

            int x = RandomUtil.randomInt(0, proxyConfigs.size());
            Console.log("随机代理" + x);
            return proxyConfigs.get(x);
        } else {
            Console.log("本机代理");
            return localConfig;
        }

    }


    private WebClient getWebClient() {
        if (webClients == null) {
            synchronized (this.getClass()) {
                if (webClients == null) {
                    this.init();
                }
            }
        }
        if (debug) {
            return localWebClient;
        }

        if (webClients.size() > 0) {

            int x = RandomUtil.randomInt(0, webClients.size());
            Console.log("随机客户端" + x);
            return webClients.get(x);
        } else {
            Console.log("本机客户端");
            return localWebClient;
        }

    }

    @Override
    public int save(WoIp entity) {
        String id = UuidUtil.getId(entity.getHost() + entity.getPort());
        entity.setId(id);
        return super.save(entity);
    }

    @Override
    @SneakyThrows
    public String staticHtml(String url) {
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(this.getProxyConfig());
        httpGet.setHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:50.0) Gecko/20100101 Firefox/50.0");
        CloseableHttpResponse response = httpClient.execute(httpGet);
        HttpEntity entity = response.getEntity();
        String html = EntityUtils.toString(entity, "utf-8");
        //  html = HttpUtil.get(url);
        return html;
    }


    @SneakyThrows
    @Override
    public String dynamicHtml(String url) {
        String html = null;
        WebClient webClient = getWebClient();

        HtmlPage page = webClient.getPage(url);
       // webClient.waitForBackgroundJavaScript(5000);
        Thread.sleep(5000);
        html = page.asXml();
        page.cleanUp();

        return html;
    }

    @Override
    public List<WebClient> getWebClients() {
        if (webClients == null) {
            getWebClient();
        }
        return webClients;
    }


}
